home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Franz PD
/
Franz PD Disk #045 (1990)(Amiga User Group Deutschland e.V.).zip
/
Franz PD Disk #045 (1990)(Amiga User Group Deutschland e.V.).adf
/
Earth-Boing
/
Earth-Boing.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-02
|
19KB
|
472 lines
/* EARTH-BOING V1.4 ....
* von Tim Pietzcker Software
* --------------------------
* Diese Version fertiggestellt :
* 29.August 1988
* Änderungen seit 1.3 :
* Geschwindigkeitssteigerung beim Füllen
*/
#include <intuition/intuition.h> /* Manager */
#include <graphics/gfxbase.h> /* Designer */
#include <graphics/gfxmacros.h> /* Special Effects */
#include <math.h> /* Clapper Holder */
#include <exec/types.h> /* Casting */
#define PI180 0.017453292 /* pi durch 180 */
#ifndef MAXBILDER
#define MAXBILDER 72 /* Anzahl der Einzelbilder für die Animation.
Kann,muß aber nicht beim Compilieren
angegeben werden,und zwar so :
cc -DMAXBILDER=n Earth-Boing
,wobei für n die gewünschte Anzahl
eingesetzt werden muß.
Mögliche Werte: Teiler von 360.
Sinnvolle Werte : 36 und 72 (bei mehr
dauert das Rechnen zu lange,und es wird
mehr Speicher verbraucht; bei weniger
wird die Animation zu ruckhaft */
#endif
struct IntuitionBase *IntuitionBase; /* als Adresse von Intuition */
struct GfxBase *GfxBase; /* " " " Graphics */
struct Library *OpenLibrary(); /* ich deklariere die Funktions-
aufrufe,die keinen 16-bit int
zurückgeben,damit ich das
Programm mit 16-bit ints
compilieren kann (sonst Guru !!)*/
struct Window *MyWindow,*OpenWindow(); /* Zeiger auf Window; s.o. */
struct Window *mw[2]; /* aufgrund des Double-Buffering
brauche ich zwei Windows während
der Animation */
struct Screen *ms[2],*OpenScreen(); /* siehe oben */
struct RastPort *rp[2]; /* s.o. */
struct ViewPort *vp[2]; /* s.o. */
struct IntuiMessage *msg,*GetMsg(); /* Zeiger auf Message */
struct BitMap myBM[MAXBILDER],*MyWindowBM[2]; /* Bitmaps,Pointers */
PLANEPTR AllocRaster(),myplane;
struct TmpRas hilfras,*InitTmpRas();
struct NewWindow TheWindow = /* jetzt die Daten für das Window,
in dem die Einzelbilder vorge-
zeichnet werden */
{
0,0, /* links oben */
212,115, /* Breite,Höhe */
0,1, /* Detail-, BlockPen */
NULL, /* IDCMP-Flags */
GIMMEZEROZERO|ACTIVATE,
/* Flags */
NULL,NULL, /* FirstGadget,CheckMark */
(UBYTE *)"Please wait a second...", /* Titel */
NULL, /* kommt noch */
NULL, /* keine selbstgebaute BitMap */
0,0,0,0, /* kein Sizing */
CUSTOMSCREEN, /* Typ */
}; /* Semikolon DARF nicht vergessen werden !! */
struct NewWindow TheWindow2 = /* die Animations-Window-Daten */
{
0,0,
640,200,
0,1,
MOUSEBUTTONS,
GIMMEZEROZERO,
NULL,NULL,
NULL,
NULL,NULL,
0,0,0,0,
CUSTOMSCREEN,
};
struct NewScreen TheScreen = /* für die zwei neuen Screens */
{
0,0,
640,200,
1,0,1,
HIRES,
CUSTOMSCREEN,
NULL,
(UBYTE *)" EARTH-BOING © 1988 by Tim Pietzcker",
NULL,
NULL,
};
/* jetzt kommt die Initialisierung der globalen Variablen (keine Lust auf
* call by reference)
*/
double sin(),cos();
int drehung=0,winkel,laenge,breite;
float x,y,z=0,za;
double sn[361],cs[361]; /* Da der Amiga am liebsten so wenig wie möglich
* rechnet,berechne ich die sinüsse und cosinüsse
* im voraus (siehe weiter unten) */
int datanz[] = { 0,31,37,5,34,20,5,11,5,4,56,3,3,7,4,4,10,117,4,4,4,6,3 };
/* Anzahl der Punkte,die die Kontinente und Inseln besitzen */
/* jetzt kommt der große Brocken - sämtliche Umrißpunktdaten (jeweils als
* Pärchen - Längengrad und Breitengrad
*/
/* Südamerika */
int erddat[] ={0,-70,12,-61,10,-56,6,-52,5,-50,0,-40,-4,-36,-6,
-35,-9,-39,-15,-41,-22,-48,-26,-49,-29,
-55,-35,-57,-35,-58,-39,-61,-39,-68,-47,
-66,-48,-70,-51,-63,-55,-70,-56,-75,-53,
-76,-49,-74,-37,-72,-30,-70,-18,-76,-14,
-81,-6,-80,0,-77,7,-75,11,-70,12,
/* Afrika */
-6,35,2,36,10,37,10,33,20,31,21,33,32,32,
36,20,44,11,51,12,50,8,47,3,39,-4,41,-14,
35,-19,35,-24,33,-26,31,-30,26,-34,19,-34,
17,-28,15,-23,12,-18,14,-11,13,-5,9,-1,10,4,
6,4,4,6,-2,5,-8,5,-12,8,-17,15,-16,21,-12,28,
-10,30,-9,32,-6,35,
/* Madagaskar */
49,-12,51,-15,47,-25,43,-25,44,-15,49,-12,
/* Antarktis */
-180,-89,-180,-85,-155,-86,-159,-77,-122,-72,
-100,-74,-100,-72,-75,-73,-70,-66,-55,-63,
-65,-68,-60,-73,-70,-80,-35,-80,-35,-77,-20,-72,
0,-70,20,-70,40,-69,53,-66,70,-67,70,-70,
80,-68,85,-66,100,-66,115,-65,120,-66,135,-65,
150,-68,166,-70,170,-72,162,-75,160,-82,
180,-85,180,-89,
/* Australien */
142,-11,148,-20,153,-25,153,-32,150,-38,140,-38,
134,-32,126,-32,119,-34,116,-33,115,-30,114,-25,
115,-22,121,-20,127,-14,130,-15,130,-11,136,-11,
135,-15,141,-18,142,-11,
/* Neuseeland */
173,-35,178,-38,170,-47,167,-46,
175,-37,173,-35,
/* Neuguinea */
130,0,134,0,136,-2,138,-1,146,-5,150,-10,145,-8,
143,-10,138,-8,138,-4,132,-3,130,0,
/* Borneo */
117,7,119,5,116,-4,110,-4,109,2,117,7,
/* Sumatra */
98,5,105,-3,104,-6,95,5,98,5,
/* Nordamerika */
-80,25,-81,25,-83,30,-95,30,-98,27,-98,22,
-95,19,-90,21,-87,21,-89,16,-84,15,-84,10,
-75,10,-85,10,-95,17,-105,20,-112,32,-117,32,
-110,23,-117,34,-120,32,-125,40,-125,48,
-130,54,-140,60,-150,60,-165,55,-158,58,
-165,62,-160,64,-166,64,-166,66,-160,66,
-166,68,-156,72,-135,69,-127,70,-110,68,
-81,70,-81,66,-95,62,-92,57,-83,55,-83,52,
-79,52,-79,55,-77,57,-78,63,-70,58,-65,60,
-56,52,-65,50,-62,45,-75,42,-76,36,-81,32,-80,25,
/* Neufundland */
-53,47,-59,48,-56,52,-53,47,
/* Kuba */
-85,22,-82,23,-75,21,-85,22,
/* Baffin */
-66,63,-77,65,-72,68,-89,70,-90,73,-79,73,
-62,66,-66,63,
/* Victoria */
-101,70,-115,70,-120,73,-105,74,-101,70,
/* Ellismere */
-80,76,-90,76,-95,82,-70,83,-80,76,
/* Grönland */
-45,60,-50,62,-55,70,-60,76,-60,76,-70,78,-40,85,
-20,80,-22,70,-40,65,-45,60,
/* Eurasien */
76,8,72,21,70,20,66,25,55,26,50,30,48,28,
52,24,56,26,60,22,57,19,52,16,44,12,41,20,
33,32,34,32,36,37,27,36,27,42,42,42,38,47,
30,46,29,42,22,40,25,38,22,36,20,40,20,42,
13,46,12,44,17,40,15,37,12,38,17,39,10,44,
7,43,3,43,3,41,0,40,0,38,-2,37,-6,36,-7,37,
-9,37,-9,43,-2,43,-2,46,-4,48,9,54,8,57,
10,58,14,54,21,55,25,66,21,65,18,62,16,56,
12,55,10,60,5,57,5,63,20,70,25,71,43,67,
65,70,70,73,80,72,80,74,105,78,112,76,113,74,
130,73,130,71,150,72,160,70,175,70,170,66,
180,65,180,63,170,60,162,60,162,56,157,52,
156,58,160,60,157,62,155,59,141,59,136,55,
141,45,140,47,134,43,128,39,129,35,126,35,
125,40,118,39,121,31,120,26,116,23,109,21,
105,19,109,16,109,11,105,10,100,14,100,8,
104,2,100,4,98,8,97,17,94,16,94,20,92,22,
88,22,80,16,80,10,76,8,
/* Großbritannien */
-5,58,-3,58,1,52,-5,50,-5,58,
/* Irland */
-7,55,-7,52,-10,52,-10,54,-5,55,
/* Island */
-22,67,-15,67,-13,65,-20,64,-22,67,
/* Japan */
141,45,145,44,140,35,130,31,130,34,139,38,141,45,
/* Sri Lanka (Ceylon) */
80,10,82,8,80,7,80,10
};
int fuelldat[] = /* Falls der Benutzer die Erdteile als aus-
gefüllte Flächen haben will,wird an den
hier angegebenen Koordinaten ein Füll-
versuch vorgenommen. Da selten ein ganzer
Kontinent auf einmal sichtbar ist,brauche
ich mehrere Füllpunkte pro Erdteil */
{ 0,-78,0,-45,-10,-70,-40, /* Südamerika */
-10,20,25,-30,40,5,30,25, /* Afrika */
46,-20, /* Madagaskar */
0,-75,90,-70,140,-75,-110,-80, /* Antarktis */
120,-30,150,-30,133,-15,145,-35, /* Australien */
176,-39, /* Neuseeland */
141,-7, /* Neuguinea */
115,0, /* Borneo */
-150,65,-70,54,-102,25,-100,40, /* Nordamerika */
-45,65,-40,75, /* Grönland */
-5,40,20,50,80,20,100,20,160,65,100,70, /* Eurasien */
-2,52, /* Großbritannien */
135,35, /* Japan */
-70,65,-80,72, /* Baffin */
-109,71, /* Victoria */
-80,80, /* Ellismere */
};
init() /* um keine Zeit mit den andauernden trans-
zendentalen Rechenoperationen zu ver-
schwenden */
{
int sch;
printf("Ich initialisiere die Sinus-Cosinus-Tabelle....\n");
for(sch=0;sch<361;sch++)
{
sn[sch] = sin ( ( (double) sch) * PI180);
cs[sch] = cos ( ( (double) sch) * PI180);
}
}
aufmachen() /* Libraries,Screens öffnen */
{
int i;
if ((IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library",0l))==NULL)
printf("Wo ist denn dieses #!?@§ Intuition ?!!\n"),exit(FALSE);
if ((GfxBase =(struct GfxBase *)
OpenLibrary("graphics.library",0l))==NULL)
printf("Wer hat mit meinem Malkasten gemalt ??\n"),exit(FALSE);
if ((ms[0] = OpenScreen(&TheScreen))==NULL)
exit (FALSE);
if ((ms[1] = OpenScreen(&TheScreen))==NULL)
CloseScreen(ms[0]),exit(FALSE);
ScreenToBack(ms[0]),ScreenToBack(ms[1]);
for (i=0;i<2;i++)
{
vp[i]=&(ms[i]->ViewPort);
SetRGB4(vp[i],0l,0l,0l,0l);
SetRGB4(vp[i],1l,15l,15l,15l);
}
}
berechne(l,b) /* Dies ist die eigentliche Rechenroutine */
int l,b; /* Werte brauchen nicht zurückgegeben werden */
{
float v,t;
l=l-drehung; /* eingestellter Drehwinkel */
if (l>359) l %=360; /* Rückführen der Werte in */
while (l<0) l +=360; /* den Bereich 0 bis 359 */
while (b<0) b +=360;
x=sn[l]*cs[b]; /* sn für sinus;cs für cosinus */
v=cs[l]*cs[b];
t=sn[b];
y=t*cs[winkel]-v*sn[winkel];
za=z;
z=t*sn[winkel]+v*cs[winkel];
}
allocate_bitmaps() /* sämtliche Einzelbilder werden in lauter */
{ /* Mini-BitMaps gespeichert (immerhin belegt */
int i,j; /* eins schon 2.5 KByte,72 Bitmaps also 180KB)! */
/* Diese BitMaps werden hier alloquiert und */
for(j=0;j<MAXBILDER;j++)/* initialisiert */
{
InitBitMap(&myBM[j],1l,201l,101l);
myBM[j].Planes[0]=AllocRaster(201l,101l);
if (myBM[j].Planes[0]==NULL) /* kein Speicher mehr frei */
{
abbruch:
for(i=j-1;i>=0;i--)
{
FreeRaster(myBM[i].Planes[0],201l,101l);
}
CloseScreen(ms[0]); /* schön saubermachen */
CloseScreen(ms[1]);
exit(FALSE);
}
}
myplane=AllocRaster(212l,115l);
if (myplane==NULL) goto abbruch;
}
main()
{
int i,j,schleife,scrsw,fuellen;
unsigned int zaehler;
long brl,brt,inc,inc2,weitermachen=TRUE,xpos,ypos,wink,
minterm=0x00C0,mask=0x00FF; /* die zwei bestimmen beim BltBitMap'en
die Art des Kopierens.So,wie sie jetzt
eingestellt sind,heißt das :genaue
Kopie */
float x1,y1;
aufmachen();
init();
allocate_bitmaps();
do { /* Dies ist die Hauptschleife.Sie wird mindestens
* einmal ausgeführt und beendet bei Eingabe von
* -1 (s.u.).Kontroll-Flag :weitermachen */
WBenchToFront();
printf("%c",12);
printf(" EARTH-BOING Version 1.4\n");
printf(" programmiert in Aztec C von Tim Pietzcker\n");
printf("\n");
printf("Bitte gib den Neigungswinkel in Grad ein (0-359,normal 23)\n");
printf("oder -1 zum Beenden :");
scanf("%d",&winkel);
if (winkel>359 || winkel<0) weitermachen=FALSE;
else weitermachen=TRUE;
if (weitermachen) /* sonst Schluß */
{
printf("Sollen Flächen ausgefüllt werden (1) oder nicht (0) ?");
scanf("%d",&fuellen);
TheWindow.Screen=ms[0];
ScreenToFront(ms[0]);
if ((MyWindow=OpenWindow(&TheWindow))==NULL) goto ende;
rp[0]=MyWindow->RPort;
rp[0]->TmpRas=InitTmpRas(&hilfras,myplane,(long)RASSIZE(212l,115l));
MyWindowBM[0]=rp[0]->BitMap;
SetAPen(rp[0],1l);
SetOPen(rp[0],1l);
SetBPen(rp[0],1l);
brl=MyWindow->BorderLeft;
brt=MyWindow->BorderTop;
for(schleife=0;schleife<=MAXBILDER-1;schleife++) /* Einzelbilder */
{
SetRast(rp[0],0l);
drehung=schleife*(360/MAXBILDER);
for (j=1,zaehler=1;j<23;j++,zaehler++) /* Kontinente/Inseln
nacheinander */
{
laenge=erddat[zaehler];
breite=erddat[++zaehler];
berechne(laenge,breite);
x1=x;
y1=y;
zaehler++;
for (i=1;i<=datanz[j];i++,zaehler++) /* einzelne Punkte */
{
laenge=erddat[zaehler];
breite=erddat[++zaehler];
berechne(laenge,breite);
if (z>=0 && za>=0) /* Hidden Lines */
{
Move(rp[0],(long)(100*x1+100),(long)(-50*y1+50));
Draw(rp[0],(long)(100*x+100),(long)(-50*y+50));
}
x1=x;
y1=y;
}
zaehler--; /* um 1 zu hoch gezählt */
}
DrawEllipse(rp[0],100l,50l,100l,50l);
if (fuellen==1)
{
DrawEllipse(rp[0],100l,50l,99l,50l);
DrawEllipse(rp[0],100l,50l,101l,51l); /* Dies ist als
"Auslaufschutz"
gedacht (hat nichts
mit PAMPERS zu tun)
*/
for(i=1;i<=74;i+=2)
{
laenge=fuelldat[i];
breite=fuelldat[i+1];
berechne(laenge,breite);
if (z>0)
Flood(rp[0],0l,(long)(100*x+100),(long)(-50*y+50));
}
SetAPen(rp[0],0l);
DrawEllipse(rp[0],100l,50l,101l,51l);
SetAPen(rp[0],1l);
}
BltBitMap(MyWindowBM[0],brl,brt,
&myBM[schleife],0l,0l,201l,101l,
minterm,mask,NULL);
/* So,dieser gigantische Befehl schneidet ein Stück aus der
BitMap von meinem Window und klebt die Kopie in eine der
36 Mini-BitMaps */
}
CloseWindow(MyWindow);
/* Jetzt haben wir alle Drehungen in lauter kleinen Bitmaps
abgelegt und können die nun für unsere Animation verwenden */
TheWindow2.Screen=ms[0];
if ((mw[0]=OpenWindow(&TheWindow2))==NULL) goto ende;
TheWindow2.Screen=ms[1];
if ((mw[1]=OpenWindow(&TheWindow2))==NULL)
{
CloseWindow(mw[0]);
goto ende;
}
rp[0]=mw[0]->RPort;
MyWindowBM[0]=rp[0]->BitMap;
rp[1]=mw[1]->RPort;
MyWindowBM[1]=rp[1]->BitMap;
inc=4,inc2=3,j=0;
xpos=0;
wink=270;
ypos=86+87*sn[wink];
scrsw=1;
while ((msg=GetMsg(mw[0]->UserPort))==NULL) /* weiter,solange noch
kein Event = Maus-
klick aufgetreten */
{
scrsw=1-scrsw;
ScreenToFront(ms[scrsw]); /* Page Flip ! */
SetRast(rp[1-scrsw],0l);
xpos+=inc; /* Position des nächsten Bildes
berechnen (invertierte nega-
tive Sinuskurve) ...*/
if (xpos>430 || xpos<0) xpos-=inc,inc=-inc;
wink+=inc2;
if (wink>360 || wink<180) wink-=inc2,inc2=-inc2;
ypos=86+87*sn[wink];
if (winkel <180) j+=inc/4; else j-=inc/4;
if (j==MAXBILDER) j=0;
if (j==-1) j=MAXBILDER-1;
BltBitMap(&myBM[j],0l,0l,MyWindowBM[1-scrsw],
xpos+brl,ypos+brt,
201l,101l,minterm,
mask,NULL );
/* ... und die BitMap wieder zurückkopieren ... */
}
ReplyMsg(msg); /* Mausklick-Message beantworten */
CloseWindow(mw[0]),CloseWindow(mw[1]); /* und aufräumen */
}
} while (weitermachen);
ende:
if (myplane) FreeRaster(myplane,212l,115l);
for (i=0;i<MAXBILDER;i++) FreeRaster(myBM[i].Planes[0],201l,101l);
/* raus mit dem Ballast */
CloseScreen(ms[0]),CloseScreen(ms[1]);
CloseLibrary(GfxBase);
CloseLibrary(IntuitionBase);
}
/* total fertig */